// VueVditor.vue
<script setup lang="ts">
import { onMounted, ref, watch, toRaw, onUnmounted, unref } from 'vue'
import Vditor from 'vditor'
import 'Vditor/dist/index.css'
import { fileUpload } from '@/api/oss'

const emit = defineEmits(['update:modelValue', 'after', 'focus', 'blur', 'esc', 'ctrlEnter', 'select'])

const props = defineProps({
  options: {
    type: Object,
    default() {
      return {}
    }
  },
  modelValue: {
    type: String,
    default: ''
  },
  height: {
    type: String,
    default: 'auto'
  }
})

const contentEditor = ref<Vditor | null>(null)
const editorRef = ref<HTMLElement | null>(null)

onMounted(() => {
  contentEditor.value = new Vditor(editorRef.value as HTMLElement, {
    ...props.options,
    value: props.modelValue,
    cache: {
      enable: false
    },
    fullscreen: {
      index: 3000
    },
    after() {
      emit('after', toRaw(contentEditor.value))
    },
    input(value: string) {
      emit('update:modelValue', value)
    },
    focus(value: string) {
      emit('focus', value)
    },
    blur(value: string) {
      emit('blur', value)
    },
    esc(value: string) {
      emit('esc', value)
    },
    ctrlEnter(value: string) {
      emit('ctrlEnter', value)
    },
    select(value: string) {
      emit('select', value)
    },
    upload: {
      handler(files: File[]): string | Promise<string> | Promise<null> | null {
        return new Promise<string>((resolve, reject) => {
          const formData = new FormData()
          for (const file of files) {
            formData.append('file', file)
          }
          fileUpload(formData)
            .then((res) => {
              const reFiles = res.data || []
              const editorInstance = unref(contentEditor)
              reFiles.forEach((v) => {
                editorInstance?.insertValue(`![${v.fileName}](${v.url})`)
              })
              resolve('')
            })
            .catch(() => {
              reject(new Error('上传失败'))
            })
        })
      }
    }
  })
})

watch(
  () => props.modelValue,
  (newVal) => {
    if (newVal !== contentEditor.value?.getValue()) {
      contentEditor.value?.setValue(newVal)
    }
  }
)

onUnmounted(() => {
  const editorInstance = unref(contentEditor)
  if (!editorInstance) return
  try {
    editorInstance?.destroy?.()
  } catch (error) {
    console.log(error)
  }
})
</script>

<template>
  <div
    class="editor-container"
    :style="{
      height: props.height
    }"
  >
    <div ref="editorRef" style="height: 100%"></div>
  </div>
</template>

<style>
.vditor-preview__action {
  display: none;
}
</style>
<style scoped lang="scss">
.editor-container {
  //height: 100%;
  width: auto;
}
</style>
